#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

#include <semaforoI.h>

#define FILOSOFOS 5
#define BANDEJA "bandeja"

void esperar (int senhal);
void controlador (int senhal);

int main (int argc, char *argv[]) {
  int pid_hijo;
  int i;

  srand((int)getpid());

  // Creación de un semáforo para controlar
  // el acceso a la bandeja de palillos (4)
  // Se inicializa a 2 (dos pares de palillos)
  crear_sem(BANDEJA, 2);

  // Se lanzan los filósofos...
  for (i = 0; i < FILOSOFOS; i++)
    switch (pid_hijo = fork()) {
    case 0:
      // Cada filósofo recibe el nombre del semáforo
      // que controla el acceso a la bandeja de palillos.
      execl("./exec/filosofo", "filosofo", BANDEJA, NULL);
      break;
    }

  // Se espera la terminación de los procesos...
  if (signal(SIGCHLD, esperar) == SIG_ERR) {
    fprintf(stderr, "No se esperó a un proceso.\n");
    exit(1);
  }

  // Manejo de Ctrol+C.
  if (signal(SIGINT, controlador) == SIG_ERR) {
    fprintf(stderr, "Terminación incorrecta.\n");
    exit(1);
  }

  while(1) // Bucle infinito de espera.
    pause(); // A la espera de Ctrol+C.

  return 0;
}

void esperar (int senhal) {
  int i;
  while (wait3(&i, WNOHANG, NULL) > 0);
}

void controlador (int senhal) {
  printf("\nCtrl+c capturada.\n");
  printf("Finalizando...\n\n");

  // Destrucción del semáforo.
  destruir_sem(BANDEJA);

  sleep(1);
  printf("OK!\n");
  // Salida del programa.
  exit(0);
}
